package com.itheima.a04.常见的bean后处理器;

import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.context.support.GenericApplicationContext;

/*
* 常见bean后处理器的作用
* */
public class A04 {
    public static void main(String[] args) {
        //GenericApplicationContext 是一个干净的容器，没有一些bean和后处理器的配置
        GenericApplicationContext context = new GenericApplicationContext();

        //用原始方法注册三个 bean
        context.registerBean("bean1", Bean1.class);
        context.registerBean("bean2", Bean2.class);
        context.registerBean("bean3", Bean3.class);
        context.registerBean("bean4", Bean4.class);

        /*拿到beanFactory的工厂，然后set值*/
        context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());

        /*将解析@Autowired @Value注解的后处理器加入到context中*/
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);

        /*将解析@Resource @PostConstruct @PreDestroy注解的后处理器加入到context中*/
        context.registerBean(CommonAnnotationBeanPostProcessor.class);

        /*通过打印可以看到，会先解析@Resource的注解，然后再解析@Autowired的注解，这就跟后处理器的排序顺序有关*/

        /*下面的后处理器是解析注解@ConfigurationProperties，会在初始化前去执行这个解析绑定*/
        ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory());

        //初始化容器
        context.refresh(); // 执行beanFactory后处理器, 添加bean后处理器, 初始化所有单例

        System.out.println(context.getBean(Bean1.class));

        //销毁容器
        context.close();

        /*
            学到了什么
                a. @Autowired 等注解的解析属于 bean 生命周期阶段(依赖注入, 初始化)的扩展功能
                b. 这些扩展功能由 bean 后处理器来完成
         */
    }
}
